package export

import (
	"bufio"
	"encoding/json"
	"fmt"
	"game/game-design/loader"
	"os"
	"strconv"
	"strings"
)

type TextJsonIO struct {
}

func (c *TextJsonIO) Read(fileFullName string, designDefine *loader.DesignDefine) ([]*loader.DesignFile, error) {
	var designFiles []*loader.DesignFile = make([]*loader.DesignFile, 0)
	file0, err := os.Open(fileFullName)
	if err != nil {
		fmt.Println(err)
		return designFiles, err
	}
	defer file0.Close()
	//TODO 修改读表

	var builder strings.Builder
	scanner := bufio.NewScanner(file0)
	for scanner.Scan() {
		line := scanner.Text()
		builder.WriteString(line)
	}

	var tempRows [][]interface{} = make([][]interface{}, 0)
	reader := strings.NewReader(builder.String())
	jdecoder := json.NewDecoder(reader)
	jdecoder.UseNumber()
	jdecoder.Decode(&tempRows)

	rows := make([][]string, 0, len(tempRows))
	for _, tempRow := range tempRows {
		row := make([]string, 0, len(tempRow))
		for _, tempV := range tempRow {
			row = append(row, fmt.Sprintf("%v", tempV))
		}
		rows = append(rows, row)
	}

	fileInfo, err := os.Stat(fileFullName)
	if err != nil {
		fmt.Println("Error getting file info:", err)
		return designFiles, err
	}
	dFile, err := loader.NewDesignFile(fileInfo.Name(), rows, designDefine)
	if err == nil {
		designFiles = append(designFiles, dFile)
	}
	return designFiles, nil
}

func (c *TextJsonIO) Write(designFile *loader.DesignFile, outputPath string, expectType string) {
	os.Mkdir(outputPath, 0755)
	if !designFile.FileNeedExport(expectType) {
		fmt.Println("导出忽略", expectType, designFile.Name)
		return
	}
	file, err := os.OpenFile(fmt.Sprintf("%s%s.json", outputPath, designFile.GetOutputName()), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
	if err != nil {
		fmt.Println("导出异常", expectType, designFile.Name, err)
		return
	}
	defer file.Close()

	marcos := make([]string, 0)
	marcos = append(marcos, designFile.Macros...)
	data, _ := json.Marshal(marcos)

	file.WriteString("[")
	file.WriteString("\n" + string(data))

	names := make([]string, 0, len(designFile.Fields))
	forms := make([]string, 0, len(designFile.Fields))
	tags := make([]string, 0, len(designFile.Fields))
	comments := make([]string, 0, len(designFile.Fields))

	for _, field := range designFile.Fields {
		needExport := designFile.FieldNeedExport(field.Tag(), expectType)
		if !needExport {
			continue
		}
		names = append(names, field.Name())
		forms = append(forms, field.Form())
		tags = append(tags, field.Tag())
		comments = append(comments, field.Comment())
	}

	fieldLines := make([][]string, 4)
	fieldLines[designFile.DesignDefine.NameOffset-1] = names
	fieldLines[designFile.DesignDefine.TypeOffset-1] = forms
	fieldLines[designFile.DesignDefine.TagOffset-1] = tags
	fieldLines[designFile.DesignDefine.CommentOffset-1] = comments

	for _, v := range fieldLines {
		data, _ := json.Marshal(v)
		file.WriteString(",")
		file.WriteString("\n" + string(data))
	}

	for _, data := range designFile.Datas {
		var jsonArray []interface{} = make([]interface{}, 0, len(data))

		for i, field := range designFile.Fields {
			needExport := designFile.FieldNeedExport(field.Tag(), expectType)
			if !needExport {
				continue
			}
			var value string = ""
			if i >= len(data) {
				value = ""
			} else {
				value = data[i]
			}
			num, err := strconv.ParseInt(value, 10, 64)
			if err == nil {
				jsonArray = append(jsonArray, num)
			} else {
				if strings.Contains(value, "_") {
					//strconv.ParseFloat能够对带有下划线的数字字符串进行解释，需要特殊处理
					jsonArray = append(jsonArray, value)
				} else {
					num, err := strconv.ParseFloat(value, 64)
					if err == nil {
						jsonArray = append(jsonArray, num)
					} else {
						jsonArray = append(jsonArray, value)
					}
				}
			}
		}
		data, _ := json.Marshal(jsonArray)
		file.WriteString(",")
		file.WriteString("\n" + string(data))
	}
	file.WriteString("\n]")
	fmt.Println("导出成功", expectType, designFile.Name)
}
